/**
 * 
 */
package datamodel.rucksack;

import java.util.Vector;


/**
 * class which represents the rucksack
 * 
 */
public class Rucksack {
	
	
	/**
	 * The (weight) capacity of this Rucksack
	 */
	private final int capacity;
	
	/**
	 * The instances of RucksackObject contained by this Rucksack
	 */
	private Vector<RucksackObject> contents = new Vector<RucksackObject>();


	/**
	 * constructor
	 * 
	 * @param capacity
	 *            the max capacity of this rucksack
	 * 
	 */
	public Rucksack(int capacity) {
		this.capacity = capacity;
	}
	
	/**
	 * Returns the contents of this Rucksack
	 * @return the contents of this Rucksack
	 */
	public Vector<RucksackObject> getElements(){
		return this.contents;
	}
	
	/**
	 * Returns the capacity of this Rucksack
	 * @return the capacity of this Rucksack
	 */
	public int getCapacity() {
		return this.capacity;
	}
	

	/**
	 * Returns the sum of the weights of the instances of {@link RucksackObject} contained in this Rucksack
	 * @return the sum of the weights of the instances of {@link RucksackObject} contained in this Rucksack
	 */
	public int getWeight(){
		int weightSum = 0;
		for (RucksackObject o : contents){
			weightSum += o.getWeight();
		}
		return weightSum;
	}
	
	/**
	 * Returns the sum of the values of the instances of {@link RucksackObject} contained in this Rucksack
	 * @return the sum of the values of the instances of {@link RucksackObject} contained in this Rucksack
	 */
	public int getValue() {
		int valueSum = 0;
		for (RucksackObject o : this.contents){
			valueSum += o.getValue();
		}
		return valueSum;
		
	}
	
	
	/**
	 * tries to add this RucksackObject to the rucksack
	 * 
	 * @param o
	 *            the RucksackObject to insert
	 * @return true if the object fits into the rucksack; otherwise false
	 */
	public boolean insert(RucksackObject o) {
		// Check if the added weight of the new object would put this Rucksack over capacity.
		if (o == null || (o.getWeight() + this.getWeight()) > this.capacity){
			// If so, return false
			return false;
		}
		// Otherwise, add the object to the contents of this Rucksack and return the result (true if successful)
		return this.contents.add(o);
		
	}
	
	/**
	 * Determines if this Rucksack is equal to a given Rucksack r
	 * @param r is the Rucksack to be compared
	 * @return true, if this Rucksack is equal to the given Rucksack r
	 */
	private boolean equals(Rucksack r){
		// If the Rucksack to compare is null, the two Rucksacks have different capacities, or the number of objects differs
		// between the Rucksacks
		if ((r == null) || (this.capacity != r.getCapacity()) || (this.contents.size() != r.getElements().size())){
			// Return false
			return false;
		} 
		// Otherwise, clone the contents of the Rucksack to be compared
		Vector<RucksackObject> contentsComparison = new Vector<RucksackObject>(r.getElements());
		// Then run through the contents of this Rucksack
		for(RucksackObject o : this.contents){
			// to check if the element is in both Rucksacks
			if(contentsComparison.contains(o)){
				// If so, remove the object from the clone and continue checking
				contentsComparison.remove(o);
			} else {
				// otherwise return false
				return false;
			}
		}
		// If all elements are present in both Rucksacks, return true
		return true;
	}
	
	public boolean equals(Object o){
		// If the object given to compare is an instance of Ruksack
		if (o instanceof Rucksack){
			// Compare the two Rucksacks
			return this.equals((Rucksack) o);
		}
		// Otherwise, return false
		return false;
	}
	


	/**
	 * Returns the number of objects contained in the Rucksack
	 * @return the number of objects contained in the Rucksack
	 */
	public int getSize(){
		return contents.size();
	}


}
